package com.mes.cloud.utils;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * javabean对象与Map对象的互相转换工具类
 */
public class BeanMapUtils {

    private static Log logger = LogFactory.getLog(BeanMapUtils.class);

    public static <T> T getMap2Bean(Map map, Class<T> beanClass) {
        T inst = null;
        try {
            Field[] fields = beanClass.getDeclaredFields();

            inst = beanClass.newInstance();

            for (Field field : fields) {
                if (field.getName().equals("serialVersionUID")) {
                    continue;
                }
                try {
                    PropertyDescriptor pd = new PropertyDescriptor(field.getName(), inst.getClass());
                    Method method = pd.getWriteMethod();
                    if (null != map.get(field.getName())) {
                        Class<?> type = field.getType();
                        String simpleName = field.getType().getSimpleName();
                        if ("Long".equals(field.getType().getSimpleName()) || "long".equals(field.getType().getSimpleName())) {
                            method.invoke(inst, StringUtils.isEmpty(map.get(field.getName()).toString()) ? null : Long.parseLong(map.get(field.getName()).toString()));
                        } else if ("Date".equals(field.getType().getSimpleName())) {
                            if ("java.util.Date".equals(field.getType())) {
                                method.invoke(inst, StringUtils.isEmpty(map.get(field.getName()).toString()) ? null : DateUtil.formatDate(map.get(field.getName()).toString()));
                            } else {
                                method.invoke(inst, StringUtils.isEmpty(map.get(field.getName()).toString()) ? null : DateUtil.formatDate(map.get(field.getName()).toString()));
                            }
                        } else if ("java.sql.Timestamp".contains(simpleName)) {
                            method.invoke(inst, StringUtils.isEmpty(map.get(field.getName()).toString()) ? null : DateUtil.getTime(map.get(field.getName()).toString()));
                        } else if ("Integer".equals(field.getType().getSimpleName()) || "int".equals(field.getType().getSimpleName())) {
                            method.invoke(inst, StringUtils.isEmpty(map.get(field.getName()).toString()) ? null : Integer.parseInt(map.get(field.getName()).toString()));
                        } else if ("Double".equals(field.getType().getSimpleName())) {
                            method.invoke(inst, StringUtils.isEmpty(map.get(field.getName()).toString()) ? null : Double.parseDouble(map.get(field.getName()).toString()));
                        } else if ("List".equals(field.getType().getSimpleName())) {
                            method.invoke(inst, null == map.get(field.getName()) ? null : (List) map.get(field.getName()));
                        } else if ("Map".equals(field.getType().getSimpleName())) {
                            method.invoke(inst, null == map.get(field.getName()) ? null : (Map) map.get(field.getName()));
                        } else if ("String".equals(field.getType().getSimpleName())) {
                            if (map.get(field.getName()).equals("")) {
                                method.invoke(inst, "");
                            } else {
                                method.invoke(inst, StringUtils.isEmpty(map.get(field.getName()).toString()) ? null : map.get(field.getName()));
                            }
                        } else {
                            method.invoke(inst, StringUtils.isEmpty(map.get(field.getName()).toString()) ? null : map.get(field.getName()));
                        }
                    }
                } catch (Exception e) {
                    logger.error(e);
                }
            }
        } catch (Exception e) {
            logger.error(e);
        }
        return inst;
    }

    public static Map getBean2Map(Object beanObj) {
        Map map = new HashMap();
        if (null == beanObj)
            return map;
        try {
            Class<?> classType = beanObj.getClass();
            Field[] fields = classType.getDeclaredFields();

            for (Field field : fields) {
                if (field.getName().equals("serialVersionUID")) {
                    continue;
                }
                try {
                    PropertyDescriptor pd = new PropertyDescriptor(field.getName(), beanObj.getClass());
                    Method method = pd.getReadMethod();
                    Object value = method.invoke(beanObj);
                    if (null != value) {
                        map.put(field.getName(), value);
                    } else {
                        if ("Long".equals(field.getType().getSimpleName()) || "Integer".equals(field.getType().getSimpleName())) {
                            map.put(field.getName(), -1);
                        } else {
                            map.put(field.getName(), "");
                        }
                    }
                } catch (Exception e) {
                    logger.error(e);
                }
            }
        } catch (Exception e) {
            logger.error(e);
        }
        return map;
    }
}
